import os
import sys
import argparse


class PartitionChecksumCalculator:
    """UBIFS分区校验值计算工具"""

    def __init__(self):
        self.crc_table = self._generate_crc_table()

    def _generate_crc_table(self):
        """生成标准CRC32表"""
        table = []
        for i in range(256):
            crc = i
            for _ in range(8):
                if crc & 1:
                    crc = (crc >> 1) ^ 0xEDB88320
                else:
                    crc >>= 1
            table.append(crc)
        return table

    def calculate_crc(self, data: bytes) -> int:
        """计算改良CRC32值（初始值0xFFFFFFFF，无最终取反）"""
        crc = 0xFFFFFFFF
        for byte in data:
            index = (crc ^ byte) & 0xFF
            crc = (crc >> 8) ^ self.crc_table[index]
        return crc

    def get_file_info(self, file_path: str) -> tuple:
        """
        获取文件信息和校验值
        :param file_path: 文件路径
        :return: (文件大小(字节), 校验值, 十六进制校验值)
        """
        # 自动处理扩展名
        if not os.path.exists(file_path):
            ubifs_path = file_path + ".ubifs"
            if os.path.exists(ubifs_path):
                file_path = ubifs_path
            else:
                raise FileNotFoundError(f"文件不存在: {file_path}")

        with open(file_path, 'rb') as f:
            data = f.read()

        file_size = len(data)
        checksum = self.calculate_crc(data)
        hex_checksum = f"0x{checksum:08X}"

        return file_size, checksum, hex_checksum


def main():
    """命令行主函数"""
    parser = argparse.ArgumentParser(
        description='UBIFS分区校验值计算工具',
        formatter_class=argparse.RawTextHelpFormatter
    )
    parser.add_argument('file', nargs='+', help='要计算的文件路径（可多个）')

    args = parser.parse_args()
    calculator = PartitionChecksumCalculator()

    # 获取第一个文件的父目录作为输出目录
    first_file = os.path.abspath(args.file[0])
    output_dir = os.path.dirname(first_file)

    # 在父目录创建config.txt文件
    output_file = os.path.join(output_dir, "config.txt")

    # 删除已存在的输出文件
    if os.path.exists(output_file):
        try:
            os.remove(output_file)
        except Exception as e:
            print(f"删除旧文件失败: {e}")
            sys.exit(1)

    # 处理所有文件并写入输出文件
    with open(output_file, 'w') as f_out:
        for file_path in args.file:
            try:
                file_size, checksum, _ = calculator.get_file_info(file_path)
                # 标准模式输出：0,文件大小,校验值
                line = f"0,{file_size},{checksum}"
                f_out.write(line)
                # 同时在控制台显示处理信息
                print(f"处理文件: {file_path}")
                print(f"处理成功值: 0,{file_size},{checksum}")
            except FileNotFoundError as e:
                print(f"错误: {e}")
            except Exception as e:
                print(f"处理文件时出错: {file_path}")
                print(f"错误详情: {str(e)}")

    print(f"config.txt已保存到: {output_file}")
    print(f"BY:小陳同学")
    print(f"Q群:1029148488")

if __name__ == "__main__":
    main()
